<?php
/**
 * @author       Sixe Team
 * @email        info@eee-eee.com
 * @url          http://www.eee-eee.com
 * @copyright    Copyright (C) 2010 - 2019 Sixe Information Technology Limited. All rights reserved.
 * @license      GNU General Public License version 2 or later; see LICENSE.txt
 * @date         2019/10/01 10:00
 */

defined('_JEXEC') or die;

use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;
use Joomla\CMS\Plugin\PluginHelper;
JLoader::register('ContentModelArticle', JPATH_ADMINISTRATOR . '/components/com_content/models/article.php');

/**
 * Item Model for an Article.
 *
 * @since  1.6
 */
class SixeWorkFlowModelArticle extends ContentModelArticle
{
	/**
	 * The prefix to use with controller messages.
	 *
	 * @var    string
	 * @since  1.6
	 */
	protected $text_prefix = 'COM_CONTENT';

	/**
	 * The type alias for this content type (for example, 'com_content.article').
	 *
	 * @var    string
	 * @since  3.2
	 */
	public $typeAlias = 'com_content.article';

	protected $option='com_content';
	protected $name='article';
	/**
	 * The context used for the associations table
	 *
	 * @var    string
	 * @since  3.4.4
	 */
	protected $associationsContext = 'com_content.item';

	protected $_item=NULL;
	

	protected function populateState()
	{
		$table = $this->getTable();
		$key = $table->getKeyName();
		// Get the pk of the record from the request.
		$pk = JFactory::getApplication()->input->getInt($key);
		$this->setState($this->getName() . '.id', $pk);
		$cparams = JComponentHelper::getParams('com_content');
		$params=JComponentHelper::getParams($this->option);
		$params->merge($cparams);
		$this->setState('params', $params);
	}


	
	/**
	 * Prepare and sanitise the table data prior to saving.
	 *
	 * @param   JTable  $table  A JTable object.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function prepareTable($table)
	{
		// Set the publish date to now
		if ($table->state == 1 && (int) $table->publish_up == 0)
		{
			$table->publish_up = JFactory::getDate()->toSql();
		}

		if ($table->state == 1 && intval($table->publish_down) == 0)
		{
			$table->publish_down = $this->getDbo()->getNullDate();
		}

		// Increment the content version number.
		$table->version++;

		// Reorder the articles within the category so the new article is first
		if (empty($table->id))
		{
			$table->reorder('catid = ' . (int) $table->catid . ' AND state >= 0');
		}
	}


	/**
	 * Method to get a single record.
	 *
	 * @param   integer  $pk  The id of the primary key.
	 *
	 * @return  mixed  Object on success, false on failure.
	 */
	public function getItem($pk = null)
	{
		
		if ($item = parent::getItem($pk))
		{
			// Convert the params field to an array.
			$registry = new Registry($item->attribs);
			$item->attribs = $registry->toArray();

			// Convert the metadata field to an array.
			$registry = new Registry($item->metadata);
			$item->metadata = $registry->toArray();

			// Convert the images field to an array.
			$registry = new Registry($item->images);
			$item->images = $registry->toArray();

			// Convert the urls field to an array.
			$registry = new Registry($item->urls);
			$item->urls = $registry->toArray();

			$item->articletext = trim($item->fulltext) != '' ? $item->introtext . "<hr id=\"system-readmore\" />" . $item->fulltext : $item->introtext;

			if (!empty($item->id))
			{
				$item->tags = new JHelperTags;
				$item->tags->getTagIds($item->id, 'com_content.article');
			}

		$this->_item=$this->getFlowContent($item->id);
		if(isset($this->_item->flow))
		{
			$item->flow=$this->_item->flow;


		}
		else
		{
			$flow=$this->getFlow($item->catid,$item->created_by);
			if(count($flow)>0)
			{
				$item->flow=$flow[0];
			}
			else
			{
				$item->flow=0;
			}


		}
		
		$item->state=$this->_item->state;
		$item->start_flow=$this->_item->start_flow;
		$item->max_flow=$this->_item->max_flow;
		$item->message=$this->_item->message;
		
		}

		// Load associated content items
		$assoc = JLanguageAssociations::isEnabled();

		if ($assoc)
		{
			$item->associations = array();

			if ($item->id != null)
			{
				$associations = JLanguageAssociations::getAssociations('com_content', '#__content', 'com_content.item', $item->id);

				foreach ($associations as $tag => $association)
				{
					$item->associations[$tag] = $association->id;
				}
			}
		}
		
		return $item;
	}


	public function getForm($data = array(), $loadData = true)
	{
		$app = JFactory::getApplication();
		$user = JFactory::getUser();

		// Get the form.
		$form = $this->loadForm('com_content.article', 'article', array('control' => 'jform', 'load_data' => $loadData));

		if (empty($form))
		{
			return false;
		}



		

		return $form;
	}


		/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  mixed  The data for the form.
	 *
	 * @since   1.6
	 */
	protected function loadFormData()
	{
		// Check the session for previously entered form data.
		$app  = JFactory::getApplication();
		$data = $app->getUserState('com_sixeworkflow.edit.article.data', array());

		if (empty($data))
		{
			$data = $this->getItem();

		}

		// If there are params fieldsets in the form it will fail with a registry object
		if (isset($data->params) && $data->params instanceof Registry)
		{
			$data->params = $data->params->toArray();
		}

		$this->preprocessData('com_content.article', $data);

		return $data;
	}





	public function save($data)
	{
		if(!isset($data['flowstate']))
		{
			$data['flowstate']=$data['state'];
		}
		if(!isset($data['flow']))
		{
			$data['flow']=0;
		}
		if($data['flowstate']==1)
		{
			$data['state']=1;
		}
		else
		{
			$data['state']=10;
		}
		
		$return=parent::save($data);
		if($return)
		{
			$recordId = $this->getState($this->getName().'.id');
			$this->saveFlowArticle($recordId,$data);

			

		}
		return $return;
	}




	public function saveFlowArticle($id,$data)
	{
			$user=JFactory::getUser();
			$data=(object)$data;
			$db=$this->getDbo();
			$query=$db->getQuery(true);
			$query->select('content_id,catid')
				  ->from('#__workflow_contents')
				  ->where('content_id='.(int)$id);
				  $db->setQuery($query);
			$temp = $db->loadObject();
			$content=new stdClass;
			$content->content_id=$id;
			$content->catid=$data->catid;
			$content->state=$data->flowstate;
			$content->flow=$data->flow;
			if($content->state==4)
			{
				$content->checked=JFactory::getDate()->toSql();
				$content->checked_by=$user->id;
			}
			elseif($content->state==5)
			{
				$content->rejected=JFactory::getDate()->toSql();
				$content->rejected_by=$user->id;
			}
			$content->message=$data->message;
			if(!isset($data->created_by) || empty($data->created_by))
			{
				$data->created_by=$user->id;
			}
			$user_flows=$this->getFlow($content->catid,$data->created_by);
			if(count($user_flows)>0)
			{
					$content->start_flow=$user_flows[0];
			}
			else
			{
					$content->start_flow=0;
			}

			if($temp)
			{
				if($data->catid != $temp->catid)
				{
					$content->flow=0;
					$data->flow_id=0;
					$query = $db->getQuery(true);
					$query->delete($query->qn('#__workflow_flows'))
					 ->where('content_id='.$id);
					$db->setQuery($query)->execute();
				}
			}

			if($content->flow < $content->start_flow)
			{
				$content->flow=$content->start_flow;
				$data->flow_id=$content->start_flow;

			}
			
			$content->created_by=$data->created_by;
			
			if($temp)
			{
				$return=$db->updateObject('#__workflow_contents', $content,'content_id');
			}
			else
			{

				$return=$db->insertObject('#__workflow_contents', $content);

			}
			$message=new stdclass;
			$message->content_id=$id;
			$message->flow=$content->flow;
			$message->from_user=$user->id;
			$message->message=$data->message;
			$message->title=$data->title;
			if($content->state==4)
			{
				$message->type=1;
				$this->SendMessage($message);
			}
			elseif($content->state==5)
			{
				$message->type=2;
				$this->SendMessage($message);
			}

			$query=$db->getQuery(true);
			$query->select('user_id')
				  ->from('#__workflow_flows')
				  ->where('content_id='.(int)$id)
				  ->where('flow_id='.(int)$data->flow_id);
				  $db->setQuery($query);
			$flow_user = $db->loadResult();
			$new_flow=new stdclass;
			$new_flow->content_id=$id;
			$new_flow->flow_id=$data->flow_id;
			$new_flow->user_id=$user->id;
			$new_flow->checked=JFactory::getDate()->toSql();
			

			if(!$flow_user)
			{
				
				$return=$db->insertObject('#__workflow_flows', $new_flow);
			}
			else
			{
				if($flow_user!=$data->created_by)
				{
					$return=$db->updateObject('#__workflow_flows', $new_flow,array('content_id','flow_id'));
				}
			}

			return $return;
	}



	public function SendMessage($message)
	{

		PluginHelper::importPlugin('content');
		$dispatcher = JEventDispatcher::getInstance();
		$db = JFactory::getDbo();
		$params=$this->getState('params');
		if($message->type==1)
		{
			$query = $db->getQuery(true);
			$query->select('a.*')
				  ->from('#__workflow_users AS a ')
				  ->join('INNER','#__workflow_categories AS wc ON wc.workflow_id=a.workflow_id ')
				  ->join('INNER','#__workflow_contents AS wa ON wa.catid=wc.category_id')
				  ->where('wa.content_id='.$message->content_id)
				  ->where('a.flow_id='.$message->flow);
				  $db->setQuery($query);
				  $temp = $db->loadObjectList();
				  $user_ids=array();
				  foreach($temp as $t)
				  {
				  	 if((int)$t->type==1)
				  	 {
				  	 	$query = $db->getQuery(true);
						$query->select('user_id')
						->from('#__user_usergroup_map')
						->where('group_id='.(int)$t->user_id);
						$db->setQuery($query);
				 		$group_user = $db->loadColumn();
				 		foreach($group_user AS $gu)
				 		{
				 			$user_ids[]=$gu;
				 		}

				  	 }
				  	 elseif((int)$t->type==2)
				  	 {
				  	 	 $user_ids[]=$t->user_id;
				  	 }
				  }
			foreach($user_ids as $ids)
			{
				$message->to_user=$ids;
				$message->created=JFactory::getDate()->toSql();
				$dispatcher->trigger('onContentPrepare', array('com_sixeworkflow.message', &$message,&$params,0));
				unset($message->title);
				$db->insertObject('#__workflow_messages', $message);
				
			}
		}
		elseif($message->type==2)
		{
			$query = $db->getQuery(true);
			$query->select('user_id')
			  ->from('#__workflow_flows')
			  ->where('content_id='.$message->content_id)
			  ->where('flow_id='.$message->flow);
			$db->setQuery($query);
			$temp = $db->loadResult();  
			if($temp)
			{
				$message->to_user=$temp;
				$message->created=JFactory::getDate()->toSql();
				$dispatcher->trigger('onContentPrepare', array('com_sixeworkflow.message', &$message,&$params,0));
				unset($message->title);
				$db->insertObject('#__workflow_messages', $message);
				
			}

		}
		
	}



	public function getFlow($catid,$user_id)
	{
		$user=JFactory::getUser($user_id);
		$groups=implode(',',$user->groups);
		$flow_id=array();
		$db = JFactory::getDbo();
		$query = $db->getQuery(true);
		$query->select('DISTINCT u.flow_id')
			  ->from('#__workflow_categories AS a')
			  ->join('LEFT','#__workflow_users AS u ON u.workflow_id=a.workflow_id')
			  ->where('a.category_id='.(int)$catid)
			  ->where('((u.type=1 AND u.user_id IN ('.$groups.')) OR (u.type=2 AND u.user_id='.$user->id.'))')
			  ->order('u.flow_id ASC');
			  $db->setQuery($query);
			  $temp = $db->loadColumn();
			  if($temp)
			  {
			  	$flow_id=$temp;
			  }
		
		return $flow_id;
	}



	public function getFlowContent($pk=null)
	{
		if(empty($pk))
		{
			$app=JFactory::getApplication();
			$pk=0;
			$view=$app->input->getCmd('view','');
			if($view=='article')
			{
				$pk=$app->input->getCmd('id',0);
			}
			elseif($view=='articleform')
			{
				$pk=$app->input->getCmd('a_id',0);
			}


		}
			$db = JFactory::getDbo();
			$query = $db->getQuery(true);
			$query->select('b.*,a.*,c.workflow_id,MAX(u.flow_id) AS max_flow')
			 	 ->from('#__workflow_contents AS a')
			 	 ->join('LEFT','#__content AS b ON b.id=a.content_id')
				  ->join('LEFT','#__workflow_categories AS c ON c.category_id=a.catid')
				  ->join('LEFT','#__workflow_users AS u ON u.workflow_id=c.workflow_id')
				  ->where('a.content_id='.$pk);
			  $db->setQuery($query);
			  $temp = $db->loadObject();

		return $temp;
	}

	public function getUserFlow($catid=null)
	{
		$user=JFactory::getUser();
		if(empty($catid))
		{
			if(empty($this->_item))
			{
				$this->_item=$this->getFlowContent();
			}
			$catid=$this->_item->catid;
		}
		return $this->getFlow($catid,$user->id);
	}



	public function publish(&$pks, $value = 1)
	{
		$user=JFactory::getUser();
		if(parent::publish($pks,$value))
		{
			if(count($pks))
			{
				$db = JFactory::getDBO();
				if($value==0)
				{
					$query = $db->getQuery(true)
					->clear()
					->update('#__workflow_contents')
					->set('state=3')
					->set('flow=start_flow')
					->where('content_id IN ('.implode(',',$pks).')');
					$db->setQuery($query)->execute();
					$query = 'DELETE f FROM #__workflow_flows AS f WHERE f.content_id IN(
					'.implode(',',$pks).') AND f.flow_id != (SELECT start_flow FROM #__workflow_contents WHERE content_id=f.content_id)';

					$db->setQuery($query)->execute();
				}
				elseif($value==1)
				{
					$maxquery=$db->getQuery(true)
						->select('MAX(u.flow_id)')
						->from('#__workflow_categories AS c')
						->join('LEFT','#__workflow_users AS u ON u.workflow_id=c.workflow_id')
			  			->where('category_id=a.catid');
					$query = $db->getQuery(true)
					->clear()
					->update('#__workflow_contents AS a')
					->set('a.state=1')
					->set('a.flow=('.$maxquery.')')
					->where('content_id IN('.implode(',',$pks).')');
					$db->setQuery($query)->execute();
					foreach($pks as $pk)
					{
						$query=$db->getQuery(true)->clear();
						$query->select('a.*,f.user_id')
				 	 	->from('#__workflow_contents AS a')
				 	 	->join('LEFT','#__workflow_flows AS f ON (f.content_id=a.content_id AND f.flow_id=a.flow)')
				 	 	->where('a.content_id='.(int)$pk);
					  	$db->setQuery($query);
						$content = $db->loadObject();
						if($content)
						{
							$new_flow=new stdclass;
							$new_flow->content_id=$content->content_id;
							$new_flow->flow_id=$content->flow;
							$new_flow->user_id=$user->id;
							$new_flow->checked=JFactory::getDate()->toSql();
							if(isset($content->user_id) && !empty($content->user_id))
							{
								$db->updateObject('#__workflow_flows', $new_flow,array('content_id','flow_id'));
							}
							else
							{
								$db->insertObject('#__workflow_flows', $new_flow);
							}
						}

					}


				}
			}
		}
		return true;
	}

}
